import api, { getResponseCount } from '@/store/api';
import useDownload from '@/hooks/useDownload';
import i18n from '@/i18n';
const { t } = i18n.global as any;
const { download } = useDownload();

export type Log = {
  additionalDataUri: string;
  date: Date;
  description: string;
  id: string;
  messageArgs: string[];
  name: string;
  severity: string;
  type: string;
  uri: string;
};

const getHealthStatus = (logs: Log[], loadedEvents: any) => {
  let status = loadedEvents ? 'OK' : '';
  for (const log of logs) {
    if (log.severity === 'Warning') {
      status = 'Warning';
    }
    if (log.severity === 'Critical') {
      status = 'Critical';
      break;
    }
  }
  return status;
};

// TODO: High priority logs should also check if Log
// is resolved when the property is available in Redfish
const getHighPriorityEvents = (logs: Log[]) =>
  logs.filter(({ severity }) => severity === 'Critical');

export const useRasLogStore = defineStore('RasLog', () => {
  const allRasLogs = ref([]);
  const loadedEvents = ref(false);

  const highPriorityEvents = computed(() =>
    getHighPriorityEvents(allRasLogs.value),
  );
  const healthStatus = computed(() =>
    getHealthStatus(allRasLogs.value, loadedEvents.value),
  );
  const setAllRasLogs = (RasLogs: any) => (
    (allRasLogs.value = RasLogs), (loadedEvents.value = true)
  );

  const getRasResource = async () => {
    return await api
      .get('/redfish/v1/Systems/system/LogServices/RasEvent')
      .catch((err) => {
        throw err;
      });
  };

  const getRasLogData = async () => {
    const postCodeLogs = await cutRasLogs(
      '/redfish/v1/Systems/system/LogServices/RasEvent/Entries',
    );
    setAllRasLogs(postCodeLogs);
  };
  const cutRasLogs = async (url: string) => {
    return await api
      .get(url)
      .then(async ({ data }) => {
        let rasLogs = data.Members.map((log: { [x: string]: any }) => {
          const {
            Id,
            Severity,
            Created,
            EntryType,
            Message,
            Name,
            AdditionalDataURI,
            MessageArgs,
          } = log;
          return {
            id: Id,
            severity: Severity,
            date: new Date(Created),
            type: EntryType,
            description: Message,
            name: Name,
            uri: log['@odata.id'],
            additionalDataUri: AdditionalDataURI,
            messageArgs: MessageArgs,
          };
        });
        if (data['Members@odata.nextLink']) {
          rasLogs = [
            ...rasLogs,
            ...(await cutRasLogs(data['Members@odata.nextLink'])),
          ];
        }
        return rasLogs;
      })
      .catch((error) => {
        console.log('Event Log Data:', error);
      });
  };

  const deleteAllRasLogs = async (data: Log[]) => {
    return await api
      .post(
        '/redfish/v1/Systems/system/LogServices/RasEvent/Actions/LogService.ClearLog',
        '',
        undefined,
      )
      .then(() => getRasLogData())
      .then(() => t('pageEventLogs.toast.successDelete', data.length))
      .catch((error) => {
        console.log(error);
        throw new Error(t('pageEventLogs.toast.errorDelete', data.length));
      });
  };
  const deleteRasLogs = async (uris = [] as string[]) => {
    const promises = uris.map((uri) =>
      api.delete(uri, undefined).catch((error) => {
        console.log(error);
        return error;
      }),
    );
    return await api
      .all(promises)
      .then((response) => {
        getRasLogData();
        return response;
      })
      .then(
        api.spread((...responses) => {
          const { successCount, errorCount } = getResponseCount(responses);
          const toastMessages = [];

          if (successCount) {
            const message = t(
              'pageEventLogs.toast.successDelete',
              successCount,
            );
            toastMessages.push({ type: 'success', message });
          }

          if (errorCount) {
            const message = t('pageEventLogs.toast.errorDelete', errorCount);
            toastMessages.push({ type: 'error', message });
          }

          return toastMessages;
        }),
      );
  };
  const downloadRasLogs = async (uris = [] as string[]) => {
    const promises = uris.map((uri) =>
      api
        .get(uri, {
          responseType: 'blob',
        })
        .then((res) => {
          const filename = res.headers['content-disposition']
            .split('filename=')[1]
            .replace(/"/g, '');
          const URL = window.URL.createObjectURL(res.data);
          download(filename, URL);
          window.URL.revokeObjectURL(URL);
          return 'success';
        })
        .catch((error) => {
          console.log(error);
          return 'failed';
        }),
    );
    return await api.all(promises).then((res) => {
      let count = 0;
      res.forEach((res) => {
        if (res === 'failed') {
          count++;
        }
      });
      if (count) {
        alert(t('pageEventLogs.modal.download', count));
      }
    });
  };
  const viewRasLog = async (url: string) => {
    const link = document.createElement('a');
    link.target = '_blank';
    link.href = url.split('/attachment')[0] + '/json';
    link.click();
  };
  return {
    allRasLogs,
    loadedEvents,
    highPriorityEvents,
    healthStatus,
    setAllRasLogs,
    getRasResource,
    getRasLogData,
    cutRasLogs,
    deleteAllRasLogs,
    deleteRasLogs,
    downloadRasLogs,
    viewRasLog,
  };
});
